package com.ywu.third.exec.standard.exec;

import com.ywu.boot.context.YwuContextHolder;
import com.ywu.boot.exception.YwuRuntimeException;
import com.ywu.common.gson.GsonUtils;
import com.ywu.common.utils.TimerIdGenerateUtil;
import com.ywu.third.exec.standard.data.YwuThirdExecLogsRepository;
import com.ywu.third.exec.standard.entity.YwuThirdExecEntity;
import com.ywu.third.exec.standard.entity.YwuThirdExecLogsEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StopWatch;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName DoThirdExecCoreService
 * @Description TODO
 * @Author GroundDemo
 * @Date 2024/10/14 11:11
 * @Version 1.0
 **/
@Service
@Slf4j
public class DoThirdExecCoreService {

    private Map<String, YwuThirdExecEngine> engineMap;

    @Autowired
    private List<YwuThirdExecEngine> engineList;

    @Autowired
    private YwuThirdExecLogsRepository logsRepository;

    private static final Object LOCK = new Object();

    /**
    * @Author GroundDemo
    * @Description 初始化map
    * @Date 11:26 2024/10/14
    * @Param []
    * @return void
    **/
    public void initEngineMap() {
        // 如果当前engineMap不为空的话，表示已初始化
        if (!CollectionUtils.isEmpty(engineMap)) {
            return;
        }
        engineMap = new HashMap<>();
        for (YwuThirdExecEngine engine : engineList) {
            String execType = engine.execType();
            engineMap.put(execType, engine);
        }
    }

    /**
    * @Author GroundDemo
    * @Description 根据脚本类型执行脚本
    * @Date 11:13 2024/10/14
    * @Param [entity]
    * @return java.lang.Object
    **/
    public String exec(YwuThirdExecEntity entity) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 初始化map
        initEngineMap();
        // 根据类型获取对应的执行引擎
        String execType = entity.getExecType();
        if (!engineMap.containsKey(execType)) {
            // 没有该类型的执行引擎
            log.error("exec engine is not exists");
            throw new YwuRuntimeException("exec engine is not exists");
        }
        YwuThirdExecEngine engine = engineMap.get(execType);
        // 调用对应的执行隐藏执行
        Object execRes = null;
        synchronized (LOCK) {
            execRes = engine.exec(entity);
        }
        String resStr;
        if (execRes instanceof String) {
            resStr = execRes.toString();
        } else {
            resStr = GsonUtils.serialize(execRes);
        }
        // 将执行记录插入到数据库中
        stopWatch.stop();
        long totalTimeMillis = stopWatch.getTotalTimeMillis();
        YwuThirdExecLogsEntity ywuThirdExecLogsEntity = new YwuThirdExecLogsEntity();
        ywuThirdExecLogsEntity.setExecTime((int) totalTimeMillis);
        ywuThirdExecLogsEntity.setId(TimerIdGenerateUtil.nextId());
        ywuThirdExecLogsEntity.setCode(entity.getCode());
        ywuThirdExecLogsEntity.setResourceId(entity.getId());
        ywuThirdExecLogsEntity.setInputInfo(entity.getExecParam());
        ywuThirdExecLogsEntity.setOutputInfo(resStr);
        ywuThirdExecLogsEntity.setExecVersion(entity.getCurrentVersion());
        ywuThirdExecLogsEntity.createInfo(YwuContextHolder.getCurrentContext().getYwuContextUser().getUserAccount());
        logsRepository.insertLog(ywuThirdExecLogsEntity);
        return resStr;
    }
}
